001 /** 002 * Created by IntelliJ IDEA. 003 * User: Wei Wang 004 * Date: Apr 16, 2003 005 * Time: 9:56:12 PM 006 */ 007 008 package EVolve.util.phasedetectors; 009 010 import EVolve.util.equators.*; 011 import EVolve.util.settings.PhaseDetectorSetting; 012 import EVolve.util.phasedetectors.phasedetectorUI.PhaseDetectorToolBarState; 013 import EVolve.Scene; 014 import javax.swing.*; 015 import java.util.*; 016 import java.awt.*; 017 018 public class HotspotPhaseDetector extends PhaseDetector{ 019 private UnorderedUnlimitedSet previous, current; 020 private final byte graduateChange = 0x0000, notChange = 0x0001; 021 private byte status[]; 022 private int noiseTolerance, sampleSize, targetSize; 023 private float threshold; 024 private final String configName = "hotspot_detector"; 025 026 private ArrayList samplePhase; 027 private UnorderedUnlimitedSet workingSet; 028 029 private JTextField[] contents; 030 private String[] tags; 031 032 public HotspotPhaseDetector() { 033 super(); 034 workingSet = new UnorderedUnlimitedSet(); 035 data.add(workingSet); 036 037 threshold = (float)0.8; 038 noiseTolerance = 2; 039 targetSize = sampleSize = 1; 040 041 samplePhase = new ArrayList(); 042 043 tags = new String[4]; 044 tags[0] = "[Noise tolerance (intervals)]"; 045 tags[1] = "[Threshold]"; 046 tags[2] = "[Sample]"; 047 tags[3] = "[Target]"; 048 049 JTextField textUpperThreshold, textNoiseTolerance; 050 JTextField textSampleSize, textTargetSize; 051 contents = new JTextField[4]; 052 contents[0] = textNoiseTolerance = new JTextField(); 053 contents[0].setColumns(2); 054 055 contents[1] = textUpperThreshold = new JTextField(); 056 contents[1].setColumns(3); 057 058 contents[2] = textSampleSize = new JTextField(); 059 contents[2].setColumns(2); 060 061 contents[3] = textTargetSize = new JTextField(); 062 contents[3].setColumns(2); 063 064 textUpperThreshold.setText(String.valueOf(threshold)); 065 textUpperThreshold.setToolTipText("Match threshold, from 0-1"); 066 textSampleSize.setText(String.valueOf(sampleSize)); 067 textSampleSize.setToolTipText("Take how many previous intervals as a sample set"); 068 textTargetSize.setText(String.valueOf(targetSize)); 069 textTargetSize.setToolTipText("Take how many intervals as a target set"); 070 textNoiseTolerance.setText(String.valueOf(noiseTolerance)); 071 textNoiseTolerance.setToolTipText("Noise tolerance"); 072 refreshDetectorParameters(); 073 } 074 075 public void reset() { 076 super.reset(); 077 workingSet = new UnorderedUnlimitedSet(); 078 data.add(workingSet); 079 samplePhase.clear(); 080 } 081 082 public String getName() { 083 return "Hotspot Detector"; 084 } 085 086 protected void refreshDetectorParameters() { 087 PhaseDetectorSetting setting = PhaseDetectorSetting.v(); 088 setting.readDataFromFile(tags, contents, configName); 089 try { 090 noiseTolerance = Integer.parseInt(contents[0].getText()); 091 threshold = Float.parseFloat(contents[1].getText()); 092 sampleSize = Integer.parseInt(contents[2].getText()); 093 targetSize = Integer.parseInt(contents[3].getText()); 094 } catch (NumberFormatException e) { 095 Scene.showErrorMessage("Format of detector configuration file is incorrect."); 096 return; 097 } 098 } 099 100 protected void autoDetectPhase() { 101 102 refreshDetectorParameters(); 103 phase.clear(); 104 samplePhase.clear(); 105 106 status = new byte[data.size()]; 107 108 if ((sampleSize<=0) || (targetSize<=0)) return; 109 110 for (int i=0; i<data.size(); i++) { 111 if (i<sampleSize) 112 continue; 113 114 float rate = parse(i); 115 116 byte currentStatus = (rate >= threshold) ? notChange : graduateChange; 117 status[i] = currentStatus; 118 } 119 } 120 121 public Component[] createDetectorParamsControls() { 122 Component returnVal[] = new Component[8]; 123 124 for (int i=0; i<tags.length; i++) { 125 String prompt = tags[i].substring(1,tags[i].length()-1) + ": "; 126 returnVal[i*2] = new JLabel(prompt); 127 returnVal[i*2+1] = contents[i]; 128 contents[i].setPreferredSize(new java.awt.Dimension(20,26)); 129 } 130 131 return returnVal; 132 } 133 134 public void collectData(long xMappedId, long yMappedId) { 135 int x = (int)(xMappedId/interval); 136 137 if (x >= data.size()) { 138 workingSet = new UnorderedUnlimitedSet(); 139 data.add(workingSet); 140 } 141 142 workingSet.addElement(yMappedId); 143 } 144 145 public void saveSetting() { 146 PhaseDetectorSetting.v().save(tags,contents,configName); 147 } 148 149 public void triggerPhases(int noiseTolerance) { 150 PhaseEntityTrigger trigger = new PhaseEntityTrigger(); 151 ArrayList triggered = trigger.gatherTiggeredPhase(data, noiseTolerance); 152 153 if (triggered.size() == 0) { 154 Scene.showErrorMessage("No phase triggered."); 155 } else 156 undoList.add(triggered); 157 } 158 159 private float parse(int checkPoint) { 160 161 float match = 0, average = targetSize; 162 163 for (int i=checkPoint; i<checkPoint+targetSize; i++) { 164 float rate = 0, factor = 1; 165 if (i >= data.size()) { 166 average = i-checkPoint+1; 167 break; 168 } 169 current = (UnorderedUnlimitedSet)data.get(i); 170 for (int j=checkPoint-1; j>=checkPoint-sampleSize; j--) { 171 if (j != checkPoint-1) factor = factor / 2; 172 previous = (UnorderedUnlimitedSet)data.get(j); 173 rate = rate + ((float)previous.intersection(current).size()/(float)previous.union(current).size())*factor; 174 } 175 match = match + rate; 176 } 177 178 return match/average; 179 } 180 181 protected void generatePhases() { 182 phase.clear(); 183 // generate phases detected automatically. 184 autoDetectPhase(); 185 int previous = status[0], noise = 0; 186 for (int i=1; i<status.length; i++) { 187 if (status[i] != previous) { 188 noise ++; 189 if (noise > noiseTolerance) { 190 if (previous == graduateChange) 191 phase.add(new Integer(i-noise)); 192 else 193 phase.add(new Integer(i-noise+1)); 194 noise = 0; 195 previous = status[i]; 196 } 197 } else { 198 noise = 0; 199 } 200 } 201 202 /*for (int i=0; i<samplePhase.size(); i++) { 203 phase.add(samplePhase.get(i)); 204 }*/ 205 206 ArrayList tobeDel = new ArrayList(); 207 for (int i=0; i<undoList.size(); i++) { 208 Object value = undoList.get(i); 209 if (value instanceof ArrayList) { 210 for (int j=0; j<((ArrayList)value).size(); j++) 211 phase.add(((ArrayList)value).get(j)); 212 } else { 213 int aPhase = ((Integer)value).intValue(); 214 if (aPhase < 0) {// a removed phase 215 for (int j=0; j<phase.size(); j++) { 216 if (((Integer)phase.get(j)).intValue() == (-1*aPhase)) { 217 tobeDel.add(new Integer(j)); 218 } 219 } 220 } else 221 phase.add(value); 222 } 223 } 224 225 int counter = 0; 226 for (int i=0; i<tobeDel.size(); i++) { 227 phase.remove(((Integer)tobeDel.get(i)).intValue()-counter); 228 counter ++; 229 } 230 } 231 232 protected void initialToolbarState() { 233 toolbarState = new PhaseDetectorToolBarState(); 234 toolbarState.selectedOption = 0; 235 toolbarState.optionsControlState = new HashMap(); 236 } 237 }